#include "portmonitorlinux.h"

#include <QtDebug>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QThread>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#define UEVENT_BUFFER_SIZE 2048

#include "lib_inc.h"

QRegExp PortMonitorLinux::mPatternAdd("");
QRegExp PortMonitorLinux::mPatternRemove("");

PortMonitorLinux::PortMonitorLinux(QList<PortFilterInfo> filters, QObject *parent) :
    PortMonitor(filters, parent),
    mMonitorThread(nullptr),
    mCppLive(-1)
{

}

void PortMonitorLinux::onStartMonitor(void* win) {
    Q_UNUSED(win);

    if (mMonitorThread) {
        return;
    }

    mMonitorThread = QThread::create([this](){monitorProc();});
    mMonitorThread->start();
}

void PortMonitorLinux::onStopMonitor() {
    if (mMonitorThread) {
        close(mCppLive);
//        mMonitorThread = nullptr;
    }
}

void PortMonitorLinux::monitorProc() {

    struct sockaddr_nl client;
    int rcvlen, ret;
    fd_set fds;
    int buffersize = 1024;
    char command[100];

    /*创建AF_NETLINK套接字*/
    mCppLive = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
    /*许该套接字复用其他端口*/
    setsockopt(mCppLive, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));

    /*绑定套接字*/

    client.nl_family = AF_NETLINK;
    client.nl_pid = getpid();
    client.nl_groups = 1; /* receive broadcast message*/
    bind(mCppLive, (struct sockaddr*)&client, sizeof(client));
//    memset(&client, 0, sizeof(client));
    while (mMonitorThread) {
        QThread::msleep(1000);
        char buf[UEVENT_BUFFER_SIZE] = { 0 };
        FD_ZERO(&fds);
        FD_SET(mCppLive, &fds);

        /*监听socket*/
        ret = select(mCppLive + 1, &fds, nullptr, nullptr, nullptr);
        if(ret < 0) continue;
        if(!(ret > 0 && FD_ISSET(mCppLive, &fds))) continue;

        /* receive data */
        rcvlen = recv(mCppLive, &buf, sizeof(buf), 0);
        if (rcvlen > 0) {
            /*提取USB节点*/
            QString msg = QString(buf);
            memset(command,0,sizeof(command));
            if (msg.startsWith("add@/")) {
                int indexFirst, indexLast;
                indexFirst = msg.indexOf("ttyUSB");
                indexLast = msg.lastIndexOf("ttyUSB");
//                if ((indexFirst == indexLast) && (indexLast >= 0)) {
//                    QThread::msleep(1000);
                    notifyPortArrival(msg.right(msg.length() - indexLast));
//                }
            } else if (msg.startsWith("remove@/")) {
                int indexFirst, indexLast;
                indexFirst = msg.indexOf("ttyUSB");
                indexLast = msg.lastIndexOf("ttyUSB");
//                if ((indexFirst == indexLast) && (indexLast >= 0)) {
//                    QThread::msleep(1000);
                    notifyPortRemoved(msg.right(msg.length() - indexLast));
//                }
            }
        }
    }
}
